package cn.jdemo.juc.CompletableFuture;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 【对象方法】
 *
 * handle 是执行任务完成时对结果的处理。
 * handle 方法和 thenApply 方法处理方式基本一样。
 * 不同的是 handle 是在任务完成后再执行，还可以处理异常的任务。
 * thenApply 只可以执行正常的任务，任务出现异常则不执行 thenApply 方法。
 *
 * 链接：https://www.jianshu.com/p/6bac52527ca4
 * @date 2020/12/1
 */
public class Demo04 {

    private static final ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2);

    public static void main(String[] args) throws Exception {
        // int x = 1/0;// Exception in thread "main" java.lang.ArithmeticException: / by zero
        Demo04.test01();
    }


    /**
     * 执行顺序:(线程1异常后，线程1后续的handler仍然执行并且可以捕获异常，线程2仍然继续执行)
     *
     * pool-1-thread-1 : num1
     *
     * pool-1-thread-1 : java.lang.ArithmeticException: / by zero
     * pool-1-thread-1 : num3
     *
     * pool-1-thread-2 : num2
     *
     * @throws Exception
     */
    public static void test01()throws Exception{
        CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " : num1");
            int x = 1/0;// 异常
            System.out.println(Thread.currentThread().getName() + " : num1"+"【VO】");
        }, es).handle((x,y)->{
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " : "+y.getMessage());
            System.out.println(Thread.currentThread().getName() + " : num3");
            return null;
        });

        future1.handleAsync((x,y)->{
            try {
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " : num2");
            return null;
        }, es);
    }

}
